home *** CD-ROM | disk | FTP | other *** search
- Parsing MIDI
- ~~~~~~~~~~~~
- First off, I suggest that you send for a copy of the MIDI specification
- from the International MIDI Association (5316 W. 57th St., Los Angeles, CA
- 90056, U.S.A). The cost for the basic specification is $40.00 for non-members.
-
- In the mean time, however, here is a quick summary of some of the most
- important aspects of MIDI:
-
- MIDI is primarily a _gestural_ language, in other words it does not
- represent sounds or even music, but rather a series of actions by a performer,
- such as hitting a key, pressing a pedal, etc. The instrument can interpret
- the messages however it chooses (for example, many instruments have a feature
- which allows the musical keyboard to be remapped to a set of non-standard
- musical frequencies, allowing non-western musical styles).
-
- MIDI data comes in a stream of bytes. Bytes which have the high bit (bit 7)
- set are _status bytes_. Bytes which have the high bit cleared are _data bytes_.
-
- Each midi message consists of a status byte followed by zero or more
- data bytes. The number of data bytes depends on the status byte.
-
- Midi messages are organized into the following general classes:
-
- Channel Messages (status bytes $80-$EF)
- System Common Messages (status bytes $F0-$F7)
- System Real-Time Messages (status bytes $F8-$FF)
-
- Channel messages are messages which are sent to specific MIDI "channels".
- Each channel message has a 4-bit channel number which is stored in bits 0-3
- of the status byte for that message. MIDI instruments generally listen to one
- or more channels, and any messages which have a channel number which the
- instrument is not listening to is ignored. In addition, a MIDI instrument
- may assign instruments or other state information on a channel-by-channel
- basis, for example channel #1 might be a trumpet sound, channel #2 an organ,
- etc.
-
- System Common messages and System Real-time messages generally cause
- global changes to the instrument. The difference between the two is that
- the latter are generally very short and tend to come rapidly.
-
- The include file "mididefs.h" supplied with CAMD lists all the types
- of status bytes (the status bytes for each type of channel message is defined
- without the channel number -- you must OR in the channel number into the
- status byte. So for example, the "Note On" messages is listed as 0x90, but
- can actually be any value between 0x90 and 0x9F, depending on the channel).
-
- Running Status: In order to increase the limited bandwidth of MIDI
- devices, a form of simple compression called running status is used.
- Basically, what this means is that you can omit a status byte if the
- previous status byte was exactly the same. So for example, if you wanted
- to turn on two notes on the same channel, instead of sending the
- byte stream:
-
- 0x92 0x41 0x12
- 0x92 0x52 0x44
-
- You could send:
-
- 0x90 0x41 0x12 0x52 0x44
-
- Note that only Channel messages may use running status. This is because
- channel messages are all fixed in length, while many types of system messages
- are variable length (They continue until the next status byte).
-
- Fortunately, if you're writing an application that uses the CAMD library,
- you don't need to worry about running status or the number of data bytes
- because CAMD automatically handles running status on both input and output,
- and knows how long each message should be. But there may be times when you
- need to deal with MIDI streams directly.
-
- The most important MIDI messages to support are "note on" and "note off".
- All other messages can simply be ignored for a minimalist implementation.
- A "note on" message consists of three bytes:
-
- status byte (0x90 plus the channel number)
- pitch (in other words, the keyboard key that was hit, 0-127,
- where 60 is middle C)
- velocity (How hard you hit the key, 1-127. 0 is a special case.
- Velocity usually affects how loudly the note is played)
-
- A "Note Off" message has exactly the same format, except that the
- status byte is (0x80 | channel number) instead of (0x90 | channel number).
-
- Most instruments support _polyphony_, which means that multiple note-on
- messages can be sent to turn on several notes at once, and then later
- note-off messages can be sent to turn them off again. Each note-off will
- turn off one note of the given pitch. The velocity field for note-offs is
- usually ignored in most instruments, but can be used for special effects
- such as decay rate.
-
- There are two additional ways to turn off a note.
-
- The first of these is to send a note-on with a velocity of zero. This
- is exactly equivalent to sending a note-off with a velocity of 64. The
- reason for this is to take greater advantage of running-status compression.
- This allows many note-on's and note-off's to be sent without changing the
- status byte.
-
- The second is the "All notes off" command. This is a special command
- supported by some instruments, and is detailed in the MIDI specification.
- You don't need to support it for a first cut implementation. The reason
- for this command is simple: Since the MIDI note-on and note-off messages
- are seperate messages, it is possible for notes to become "stuck" if the
- MIDI cable is unplugged (or other transmission problem occurs, such as
- crashing the computer) between the note-on and the note-off command.
- Since the note-off command never arrived, the note will continue to play
- (annoying everyone in the room) even if the cable is plugged back in.
- (Note that unlike serial cables, it is electically safe to abuse MIDI cables
- this way). "All Notes Off" is a conveniant way to silence everything on a
- channel.
-